package com.mysteel.cyx.demo.biz.threadlocal;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 此单元测试:会抛出拒绝策略
 * 原因:1.队列长度小于 for 循环中一次放进来的任务数。
 *     2.核心线程数和最大线程数个数一致。
 *
 * 排查:一次性提交的任务数量大于队列长度就有可能会触发。因为线程池核心线程都启动之后，任务提交都是先进队列。
 * 当你把最大线程数设置等于核心线程数时，根本就没有最大线程数可以用，所以会触发拒绝策略。当你把最大线程数设置大于核心线程数时，
 * 在最大线程数用完了的情况下，会触发拒绝策略。
 *
 * 改进方案:1.设置队列长度比任务数大;核心和最大线程数最好不一致
 * 改进方案:2.使用SynchronousQueue队列
 * 作者：why技术
 * 链接：https://juejin.cn/post/7329028515382313012
 *
 * @Author：cyx
 * @Date：2024/4/15 10:00
 */
public class ThreadPoolTest {

    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(64, 64,
            0, TimeUnit.MINUTES, new ArrayBlockingQueue<>(32));

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            CountDownLatch countDownLatch = new CountDownLatch(34);
            for (int j = 0; j < 34; j++) {
                threadPoolExecutor.execute(() -> {
                            try {

                            } catch (Exception e) {
                                e.printStackTrace();
                            }finally {
                                countDownLatch.countDown();
                            }
                        }
                );
            }
            try {
                countDownLatch.await();
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println("========详情任务执行完成");
        }
        System.out.println("========总任务执行完成");
    }


    //简化版
//    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 2,
//            0, TimeUnit.MINUTES, new ArrayBlockingQueue<>(1));
//
//    public static void main(String[] args) throws InterruptedException {
//        for (int i = 0; i < 100; i++) {
//            Thread.sleep(100);
//            System.out.println("第" + i + "次提交任务");
//            for (int j = 0; j < 2; j++) {
//                threadPoolExecutor.execute(() -> {
//                            try {
//
//                            } catch (Exception e) {
//                                e.printStackTrace();
//                            }
//                        }
//                );
//
//
//            }
//        }
//        System.out.println("========总任务执行完成");
//    }
}
